package com.ellecity06.cwhiskymall.ui.live

import android.graphics.Color
import android.view.LayoutInflater
import android.view.SurfaceHolder
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.aliyun.player.AliPlayer
import com.aliyun.player.AliPlayerFactory
import com.aliyun.player.IPlayer
import com.aliyun.player.bean.ErrorInfo
import com.aliyun.player.source.UrlSource
import com.cicada.player.utils.Logger
import com.ellecity06.common.base.BaseMvvmFragment
import com.ellecity06.common.ktx.isFoldExpandStatus
import com.ellecity06.common.ktx.load
import com.ellecity06.common.ktx.loadGif
import com.ellecity06.common.ktx.observeEvent
import com.ellecity06.common.utils.appContext
import com.ellecity06.common.utils.gson
import com.ellecity06.common.utils.logD
import com.ellecity06.cwhiskymall.BuildConfig
import com.ellecity06.cwhiskymall.R
import com.ellecity06.cwhiskymall.bean.response.LiveRoomResponse
import com.ellecity06.cwhiskymall.constant.BusConstants
import com.ellecity06.cwhiskymall.databinding.FragmentLiveBinding
import com.ellecity06.cwhiskymall.ui.live.player.LivePlayerActivity
import com.ellecity06.cwhiskymall.ui.live.player.LivePlayerIntent
import com.ellecity06.cwhiskymall.ui.live.player.LivePlayerState
import com.jeremyliao.liveeventbus.LiveEventBus
import kotlinx.coroutines.delay


/**
 * @author ellecity06
 * @time 2024/10/22 14:53
 * @des 直播
 */
class LiveFragment : BaseMvvmFragment<FragmentLiveBinding, LiveViewModel>(), View.OnClickListener,
    IPlayer.OnRenderingStartListener, IPlayer.OnPreparedListener, IPlayer.OnErrorListener, SurfaceHolder.Callback {
    /**
     * 阿里云播放器预备播放
     */
    private var isPulling = false
    private val mAliPlayer: AliPlayer by lazy {
        AliPlayerFactory.createAliPlayer(appContext).apply {
            isAutoPlay = false
            // 设置直播不缓存
            setOnRenderingStartListener(this@LiveFragment)
            setOnPreparedListener(this@LiveFragment)
            setOnErrorListener(this@LiveFragment)
        }
    }
    companion object {
        @JvmStatic
        fun newInstance(): LiveFragment {
            return LiveFragment()
        }

    }
    override fun lazyInit() {
        binding.viewToLiveRoom.setOnClickListener(this)
        Logger.getInstance(requireActivity()).enableConsoleLog(!BuildConfig.SERVER_RELEASE)
        Logger.getInstance(requireActivity()).logLevel = Logger.LogLevel.AF_LOG_LEVEL_TRACE
        collectPageState()
        collectEvent()
        binding.surfaceView.holder.addCallback(this)
//        fetchLiveRoom()
        fetchCover()

    }
    private fun collectEvent() {
        LiveEventBus.get<Boolean>(BusConstants.LIVE_STATUS_EVENT).observe(this) {
            if (it) {
                fetchLiveRoom()
            } else {
                hideLive()
            }
        }
    }
    private fun collectPageState() {
        viewModel.state.observeEvent(this) {
            when (it) {
                is LivePlayerState.HasLiveRoom -> {
                    showLive(it.liveRoom)
                }

                LivePlayerState.NoLiveRoom -> {
                    hideLive()
                }
                is LivePlayerState.OtherSettingValue -> {
                    binding.ivCover.load(requireActivity(), it.value)
                }
                else -> {}
            }
        }
    }

    private fun fetchCover() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.OtherSettingValue)
        }
    }
    override fun inflateBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLiveBinding {
        return FragmentLiveBinding.inflate(inflater, container, false)
    }

    private fun showLive(liveRoomResponse: LiveRoomResponse) {
        binding.ivPlaying.loadGif(requireActivity(), R.drawable.gif_live_playing)
        binding.tvLiveRoomName.text = liveRoomResponse.liveRoomName
        binding.tvLecturerName.text = liveRoomResponse.lecturerName
        preparePlay(liveRoomResponse.pullUrl)
        showLiveView()
    }

    private fun showLiveView() {
        binding.layoutLive.visibility = View.VISIBLE
        binding.ivCover.visibility = View.GONE
    }
    private fun hideLive() {
        binding.layoutLive.visibility = View.GONE
        binding.ivCover.visibility = View.VISIBLE
        stopPlay()
    }

    private fun stopPlay() {
        isPulling = false
        mAliPlayer?.stop()
    }
    private fun preparePlay(pullUrl: String?) {
        isPulling = true
        if (pullUrl.isNullOrEmpty()) {
            return
        }
        val config = mAliPlayer.config
        config?.mEnableLocalCache = false
        config?.mMaxDelayTime = 1000
        config?.mHighBufferDuration = 100
        config?.mStartBufferDuration = 100
        config?.mEnableSEI = true

        if (!isFoldExpandStatus()) {
            mAliPlayer.scaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FILL
        } else {
            mAliPlayer.scaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FIT
        }
        mAliPlayer.setVideoBackgroundColor(Color.BLUE)
        val source = UrlSource()
        source.uri = pullUrl
        if (config != null) {
            mAliPlayer?.config = config
            mAliPlayer?.setDataSource(source)
            mAliPlayer?.prepare()
            mAliPlayer.start()
        }
    }
    private fun fetchLiveRoom() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.FetchLiveRoomList)
        }
    }
    private fun fetchLiveStatus() {
        lifecycleScope.launchWhenCreated {
            viewModel.intentChannel.send(LivePlayerIntent.FetchLiveRoomDetail(viewModel.currentLiveItem?.pullId))
        }
    }
    override fun onDestroy() {
        logD("liveFragment onDestroy")
        super.onDestroy()
        releasePlay()
    }

    private fun releasePlay() {
        stopPlay()
        mAliPlayer?.setSurface(null)
        mAliPlayer?.release()
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            binding.viewToLiveRoom.id -> {
                viewModel.currentLiveItem?.let {
                    LivePlayerActivity.launch(requireActivity(), it)
                }

            }
        }
    }

    override fun onRenderingStart() {

    }

    override fun onPrepared() {
        // 预加载完成
        logD("阿里云播放器加载预加载完成")
        //准备完毕后延迟显示，防止闪黑屏
        lifecycleScope.launchWhenCreated {
            delay(200)
            binding.surfaceView.visibility = View.VISIBLE
        }
    }

    override fun onError(p0: ErrorInfo?) {
        logD("阿里云播放器播放出错了=${gson.toJson(p0)}")
//        if (mAliPlayer != null) {
//            mAliPlayer?.reload()
//        }
        // 直播间状态正常的时候就不请求了,只有错误
        fetchLiveStatus()
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        mAliPlayer?.setSurface(holder.surface)
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
        mAliPlayer?.surfaceChanged()
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        mAliPlayer?.setSurface(null)
    }


    override fun onResume() {
        super.onResume()
        // 如果当前没有直播，那就请求列表的接口
        if (viewModel.currentLiveItem == null) {
            fetchLiveRoom()
            return
        }
        // 查询这个直播间状态,这个时候表示有直播间的，但是直播间状态是异常的 ，所以要查询是否正常 当前没有直播
        if (viewModel.currentLiveItem != null && viewModel.currentLiveItem?.liveStatus != 1) {
            fetchLiveStatus()
            return
        }
        showLiveView()
        preparePlay(viewModel.currentLiveItem?.pullUrl)
        mAliPlayer?.start()

    }

    override fun onPause() {
        super.onPause()
        //停止播放
        binding.surfaceView.visibility = View.INVISIBLE
        stopPlay()
        logD("liveFragment onPause")
    }
    override fun onDestroyView() {
        super.onDestroyView()
releasePlay()
        logD("liveFragment onDestroyView")

    }
}